1   /**
2    * Copyright 2014 Netflix, Inc.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package rx;
17  
18  import org.junit.Test;
19  
20  import rx.CovarianceTest.CoolRating;
21  import rx.CovarianceTest.ExtendedResult;
22  import rx.CovarianceTest.HorrorMovie;
23  import rx.CovarianceTest.Media;
24  import rx.CovarianceTest.Movie;
25  import rx.CovarianceTest.Rating;
26  import rx.CovarianceTest.Result;
27  import rx.functions.Action1;
28  import rx.functions.Func2;
29  import rx.subjects.BehaviorSubject;
30  
31  import static org.junit.Assert.assertNull;
32  import static rx.Observable.combineLatest;
33  
34  public class CombineLatestTests {
35      /**
36       * This won't compile if super/extends isn't done correctly on generics
37       */
38      @Test
39      public void testCovarianceOfCombineLatest() {
40          Observable<HorrorMovie> horrors = Observable.just(new HorrorMovie());
41          Observable<CoolRating> ratings = Observable.just(new CoolRating());
42  
43          Observable.<Movie, CoolRating, Result> combineLatest(horrors, ratings, combine).toBlocking().forEach(action);
44          Observable.<Movie, CoolRating, Result> combineLatest(horrors, ratings, combine).toBlocking().forEach(action);
45          Observable.<Media, Rating, ExtendedResult> combineLatest(horrors, ratings, combine).toBlocking().forEach(extendedAction);
46          Observable.<Media, Rating, Result> combineLatest(horrors, ratings, combine).toBlocking().forEach(action);
47          Observable.<Media, Rating, ExtendedResult> combineLatest(horrors, ratings, combine).toBlocking().forEach(action);
48  
49          Observable.<Movie, CoolRating, Result> combineLatest(horrors, ratings, combine);
50      }
51  
52      Func2<Media, Rating, ExtendedResult> combine = new Func2<Media, Rating, ExtendedResult>() {
53          @Override
54          public ExtendedResult call(Media m, Rating r) {
55              return new ExtendedResult();
56          }
57      };
58  
59      Action1<Result> action = new Action1<Result>() {
60          @Override
61          public void call(Result t1) {
62              System.out.println("Result: " + t1);
63          }
64      };
65  
66      Action1<ExtendedResult> extendedAction = new Action1<ExtendedResult>() {
67          @Override
68          public void call(ExtendedResult t1) {
69              System.out.println("Result: " + t1);
70          }
71      };
72  
73      @Test
74      public void testNullEmitting() throws Exception {
75          Observable<Boolean> nullObservable = BehaviorSubject.create((Boolean) null);
76          Observable<Boolean> nonNullObservable = BehaviorSubject.create(true);
77          Observable<Boolean> combined =
78                  combineLatest(nullObservable, nonNullObservable, new Func2<Boolean, Boolean, Boolean>() {
79                      @Override
80                      public Boolean call(Boolean bool1, Boolean bool2) {
81                          return bool1 == null ? null : bool2;
82                      }
83                  });
84          combined.subscribe(new Action1<Boolean>() {
85              @Override
86              public void call(Boolean aBoolean) {
87                  assertNull(aBoolean);
88              }
89          });
90      }
91  }